package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.exception.LogicException;
import cn.wolfcode.wolf2w.redis.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.repository.UserInfoRepository;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.AssertUtils;
import cn.wolfcode.wolf2w.util.Consts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;

@Service
public class UserInfoServiceImpl implements IUserInfoService {
    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public void save(UserInfo userInfo) {
        userInfoRepository.save(userInfo);
    }

    @Override
    public void update(UserInfo userInfo) {
        userInfoRepository.save(userInfo);
    }

    @Override
    public void delete(String id) {
        userInfoRepository.deleteById(id);
    }

    @Override
    public UserInfo get(String id) {
        return userInfoRepository.findById(id).orElse(null);
    }

    @Override
    public List<UserInfo> listAll() {
        return userInfoRepository.findAll();
    }

    @Override
    public boolean checkPhone(String phone) {
        UserInfo userInfo = userInfoRepository.findByPhone(phone);
        return userInfo != null;
    }

//    @Value("${sms.url}")
//    private String url;
//    @Value("${sms.appkey}")
//    private String appkey;

    @Override
    public void sendVerifyCode(String phone) {
        // 1、获取手机号，生成短信验证码
        String code = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4);
        // 2、拼接成短信
        StringBuilder sb = new StringBuilder(80);
        sb.append("【创信】您好！您的验证码是：").append(code).append("，请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟内使用。谢谢！");
        // 3、发送短信到手机上（假的）
        System.out.println(sb);
        // 真正发送短信，本质上是用java发起http请求，Spring MVC提供一个工具类 RestTemplate用来发送请求
//        RestTemplate template = new RestTemplate();
//        //String url = "https://way.jd.com/chuangxin/dxjk?mobile=18276519908&content=【创信】你的验证码是：5873，3分钟内有效！&appkey=d945b0ab65e9aac8de7b90558e19787a";
//        // String url = "https://way.jd.com/chuangxin/dxjk?mobile={1}&content={2}&appkey={3}";
//        // 参数：短信的url，请求接口完后将数据封装成的对象，请求参数列表
//        // getForObject get请求，返回类型
//        // String ret = template.getForObject(url, String.class);
//        // String ret = template.getForObject(url, String.class,phone,sb.toString(),"d945b0ab65e9aac8de7b90558e19787a");
//        String ret = template.getForObject(url, String.class,phone,sb.toString(),appkey);
//
//        // 判断是否发送成功
//        if (!ret.contains("Success")){
//            throw new LogicException("短信发送失败！");
//        }

        // 4、将手机作为key后缀，验证码作为value存进redis中
        userInfoRedisService.setVerifyCode(phone,code);
    }

    @Override
    public void regist(String phone, String nickname, String password, String rpassword, String verifyCode) {
        // 1、接收所有的参数进行校验：非空
//        if(!StringUtils.hasLength(nickname)){ throw  new RuntimeException("昵称不能为空！");}   // 代码臃肿，麻烦
//        Assert.hasLength(nickname,"昵称不能为空！");   // 抛出的是 非法参数异常，后面需要对这些用户异常进行控制
        AssertUtils.hasLength(phone,"手机号不能为空！");
        AssertUtils.hasLength(nickname,"昵称不能为空！");
        AssertUtils.hasLength(password,"密码不能为空！");
        AssertUtils.hasLength(rpassword,"确认密码不能为空！");
        AssertUtils.hasLength(verifyCode,"验证码不能为空！");
        // 2、校验两次密码是否一致
        AssertUtils.isEqual(password,rpassword,"两次的密码不一致！");
        // 3、手机格式和唯一性的校验
        String regex = "^1[3456789]\\d{9}$";
        if (!phone.matches(regex)){
            throw new LogicException("手机号码格式不正确！");
        }
        if (this.checkPhone(phone)){
            throw new LogicException("该手机号已经被注册！");
        }
        // 4、验证码的校验：（1）从redis中获取发送的验证码 （2）拿前端输入地方验证码 和 redis获取的验证码进行对比，判断是否一致
        String code = userInfoRedisService.getVerifyCode(phone);
        if (!StringUtils.hasLength(code) || !code.equalsIgnoreCase(verifyCode)){
            throw new LogicException("验证码失效或错误！");
        }
        // 5、用户注册，将用户信息保存到数据库中
        UserInfo userInfo = new UserInfo();
        userInfo.setNickname(nickname);
        userInfo.setPhone(phone);
        userInfo.setEmail("");
        userInfo.setPassword(password);  // 假装加密
        userInfo.setGender(UserInfo.GENDER_SECRET);
        userInfo.setLevel(0);
        userInfo.setCity("");
        userInfo.setHeadImgUrl("/images/default.jpg");  // 默认使用前端页面的图片
        userInfo.setInfo("");
        userInfo.setState(UserInfo.STATE_NORMAL);  // 核心属性必须自己设置进去，这样写，方便以后的维护
        userInfo.setId(null);
        userInfoRepository.save(userInfo);  // 保存到数据库
    }

    @Override
    public UserInfo userLogin(String username, String password) {
        // 判断非空（或者使用if判断）
        AssertUtils.hasLength(username,"用户名不能为空！");
        AssertUtils.hasLength(password,"密码不能为空！");

        // 通过手机号找用户信息
        UserInfo user = userInfoRepository.findByPhone(username);
        if (user == null || !password.equals(user.getPassword())){
            throw new LogicException("用户名或者密码错误！");
        }
        user.setPassword(null);  // 密码不暴露出去
        return user;
    }

    @Override
    public List<UserInfo> findByCity(String city) {
        return userInfoRepository.findByCity(city);
    }
}
